#include "config.h"
#include <string.h>

#include "xIPC.h"
#include "aux_types.h"
#include "aux_errno.h"
#include "aux_debugmsg.h"
#include "aux_datacheck.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>


#define BUFSIZE     1024*4

static unsigned int crc_table[256];
const static char * program_name = "crc32";

static void usage(void);
static void init_crc_table(void);
static unsigned int crc32(unsigned int crc, unsigned char * buffer, unsigned
int size);
static int calc_img_crc(const char * in_file, unsigned int * img_crc);

static void usage(void)
{
    fprintf(stderr, "Usage: %s input_file\n", program_name);
}

/*
 * init crc table, generate 32bits crc table.
 * 256 total
 */
static void init_crc_table(void)
{
    unsigned int c;
    unsigned int i, j;

    for (i = 0; i < 256; i++)
    {
        c = (unsigned int)i;

        for (j = 0; j < 8; j++)
        {
            if (c & 1)
                c = 0xedb88320L ^ (c >> 1);
            else
                c = c >> 1;
        }

        crc_table[i] = c;
    }
}

/* calculate the crc value of table */
static unsigned int crc32(unsigned int crc,unsigned char *buffer, unsigned
int size)
{
    unsigned int i;

    for (i = 0; i < size; i++)
    {
        crc = crc_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8);
    }

    return crc ;
}
#if 0

static int calc_img_crc(const char *in_file, unsigned int *img_crc)
{
    int fd;
    int nread;
    int ret;
    unsigned char buf[BUFSIZE];
    unsigned int crc = 0xffffffff;

    fd = open(in_file, O_RDONLY);
    if (fd < 0)
    {
        printf("%d:open %s.\n", __LINE__, strerror(errno));
        return -1;
    }

    while ((nread = read(fd, buf, BUFSIZE)) > 0)
    {
        crc = crc32(crc, buf, nread);
    }

    *img_crc = crc;

    close(fd);

    if (nread < 0)
    {
        printf("%d:read %s.\n", __LINE__, strerror(errno));
        return -1;
    }

    return 0;
}

int main_test(int argc, char **argv)
{
    int ret;
    unsigned int img_crc;
    const char *in_file = argv[1];

    if (argc < 2)
    {
        usage();
        exit(1);
    }

    init_crc_table();

    ret = calc_img_crc(in_file, &img_crc);
    if (ret < 0)
    {
        exit(1);
    }

    printf("The crc of %s is:%u\n", in_file, img_crc);

    return 0;
}
#endif

EErrNo xIPCDataCheckCalcResult(u8 *pbyData, u32 nSize, u32 *pnResult)
{
    if (!pbyData || !nSize || !pnResult)
        return -ERRNO_EPARAMETER_INVALID;

    *pnResult = crc32(0xa55a, pbyData, nSize);
    return ERRNO_SUCCESS;
}

EErrNo xIPCDataCheckDataValid(u8 *pbyData, u32 nSize, u32 nResult)
{
    u32 nRet;

    if (!pbyData || !nSize)
        return -ERRNO_EPARAMETER_INVALID;

    if (ERRNO_SUCCESS != xIPCDataCheckCalcResult(pbyData, nSize, &nRet))
        return ERRNO_FAIL;

    if (nResult == nRet)
        return ERRNO_TRUE;
    else
        return ERRNO_FALSE;
}



EErrNo xIPCComponentDataCheckInit(void)
{
    init_crc_table();
    return ERRNO_SUCCESS;
}

EErrNo xIPCComponentDataCheckDeinit(void)
{
    return ERRNO_SUCCESS;
}
